/**
 * axios 通用封装
 * @version 2.2.0
 */
import axios from 'axios';
import { createPinia } from 'pinia';
import AuthStore from '@/stores/AuthStore';
import router from '../router';
import { ElMessage } from 'element-plus';

const authStore = AuthStore(createPinia());

const mockStatus = !((import.meta.env.VITE_MOCKJS_STATUS?.toUpperCase() != 'TRUE') && import.meta.env.VITE_API_BASE_URL);

// 创建 axios 实例，避免污染原生 axios 实例。
const esaxios = axios.create({
    baseURL: mockStatus ? '' : import.meta.env.VITE_API_BASE_URL,
    defaults: {
        headers: {
            'Content-Type': 'application/json',
        },
        timeout: 6000,
    },
    // withCredentials: true, // 跨域携带 cookie.domain
});

/**
 * 处理网络错误
 * @param {Number} errStatus 
 * @param {String} errMessage 
 * @returns 
 */
export const handleNetworkError = (errStatus, errMessage = '') => {
    const networkErrMap = {
        "400": "错误的请求", // token 失效
        "401": "未授权，请重新登录",
        "403": "拒绝访问",
        "404": "请求错误，未找到该资源",
        "405": "请求方法未允许",
        "408": "请求超时",
        "500": "服务器端出错",
        "501": "网络未实现",
        "502": "网络错误",
        "503": "服务不可用",
        "504": "网络超时",
        "505": "Http 版本不支持该请求",
    };
    if (errStatus) {
        ElMessage.error(networkErrMap[errStatus.toString()] ?? `网络连接错误（${errStatus})`);
        return;
    }
    console.warn('【网络连接错误】，请检查 URL 是否可正常访问，检查服务端是否允许跨域访问。');
    ElMessage.error("无法连接到服务器！" + errMessage);
};

/**
 * 处理授权错误
 * @param {Number} errno 
 * @returns 
 */
export const handleAuthError = (errno) => {
    const authErrMap = {
        "40031": "登录失效，需要重新登录", // token 失效
        "40032": "您太久没登录，请重新登录~", // token 过期
        "40033": "账户未绑定角色，请联系管理员绑定角色",
        "40034": "该用户未注册，请联系管理员注册用户",
        "40035": "code 无法获取对应第三方平台用户",
        "40036": "该账户未关联员工，请联系管理员做关联",
        "40037": "账号已无效",
        "40038": "账号未找到",
    };

    if (authErrMap.hasOwnProperty(errno)) {
        ElMessage.error(authErrMap[errno]);
        // 授权错误，登出账户
        authStore.logout();
        router.push('/login');
        return false;
    }
    return true;
};

/**
 * 处理通用错误
 * @param {Number} errno 
 * @returns 
 */
export const handleCommonError = (errno, message) => {
    if (parseInt(errno) != 200 && message.length > 0) {
        ElMessage.error(message);
        return false;
    }
    return true;
};

/**
 * 请求拦截器
 */
esaxios.interceptors.request.use(
    config => {
        config.headers.Authorization = authStore.getToken();
        console.log('axios 请求拦截器 config', config);
        return config;
    },
    err => {
        console.log('axios 请求拦截器 err', err);
        return Promise.reject(err)
    }
)

/**
 * 输出拦截器
 */
esaxios.interceptors.response.use(
    res => {
        console.log('axios 输出拦截器 res', res);
        if (res.status !== 200) {
            handleNetworkError(res.status);
            return Promise.reject(res);
        }
        if (typeof (res.data.code) != 'undefined' && typeof (res.data.message) != 'undefined') {
            if (!handleAuthError(res.data.code) || !handleCommonError(res.data.code, res.data.message)) {
                return Promise.reject(res);
            }
        }
        return Promise.resolve(res.data);
    },
    err => {
        console.log('axios.interceptors.response err', err);
        handleNetworkError(err.response?.status || '', err.message)
        return Promise.reject(err)
    }
)

/**
 * 模拟请求数据
 */
esaxios.promiseResult = (data) => {
    return new Promise(resolve => {
        resolve(data);
    })
}

export { esaxios };